//记录Promise的三种状态
const PENDING = "pending";
const FULLFILLED = "fullfilled";
const REJECTED = "rejected";

/**
 * 运行一个微队列任务
 * 把传递的函数放到微队列中
 * @param {Function} callback
 */
function runMicroTask(callback) {
    // 判断node环境
    if (typeof process != "undefined" && process.nextTick) {
        //node环境的process.nextTick就是一个微队列函数
        process.nextTick(callback);
    } else if (MutationObserver) {
        //浏览器环境
        const p = document.createElement("p");
        const observer = new MutationObserver(callback);
        observer.observe(p, {
            childList: true,
        });
        p.innerHTML = "1";
    }
}

/**
 * 判断一个数据是不是Promise对象
 * @param {*} obj
 * @returns
 */
function isPromise(obj) {
    return !!(obj && typeof obj === "object" && typeof obj.then === "function");
}
class MyPromise {
    /**
     * 创建一个Promise
     * @param {Function} executor 任务执行器，立即执行
     */
    constructor(executor) {
        this._state = PENDING;
        this._value = undefined;
        this._handlers = [];
        try {
            executor(this._resolve.bind(this), this._reject.bind(this));
        } catch (error) {
            this._reject(error);
        }
    }

    /**
     * 向处理队列中添加一个函数
     * @param {Function} executor 添加的函数
     * @param {String} state 该函数什么状态下执行
     * @param {Function} resolve 让then函数返回的promise成功
     * @param {Function} reject 让then函数返回的promise失败
     */
    _pushHandler(executor, state, resolve, reject) {
        this._handlers.push({
            executor,
            state,
            resolve,
            reject,
        });
    }

    /**
     * 根据实际情况，执行队列
     * @returns
     */
    _runHandlers() {
        if (this._state === PENDING) {
            //目前任务仍在挂起
            return;
        }
        while (this._handlers[0]) {
            //保证每个函数只运行一次，不会执行多次
            const handler = this._handlers[0];
            this._runOneHandler(handler);
            this._handlers.shift();
        }
    }
    /**
     * 处理一个handler
     * @param {Object} handler
     */
    _runOneHandler({ executor, state, resolve, reject }) {
        runMicroTask(() => {
            if (this._state !== state) {
                //状态不一致，不处理
                return;
            }
            if (typeof executor !== "function") {
                //传递后续处理并非一个函数，那么穿透
                this._state === FULLFILLED ? resolve(this._value) : reject(this._value);
                return;
            }
            try {
                const result = executor(this._value);
                if (isPromise(result)) {
                    result.then(resolve, reject); //如果返回值是一个Promise,那么让then函数返回的promise和这个promise一致
                } else {
                    resolve(result);
                }
            } catch (error) {
                //如果后续处理函数抛出异常，那么让then函数返回的promise失败
                handler.reject(error);
            }
        });
    }
    /**
     *
     * @param {String} newState 新状态
     * @param {*} value 相关数据
     */
    _changeState(newState, value) {
        if (this._state !== PENDING) {
            //目前状态已更改
            return;
        }
        this._state = newState;
        this._value = value;
        this._runHandlers(); //状态变化，执行队列
    }
    /**
     * 标记当前任务完成
     * @param {any} data 任务完成的相关数据
     */
    _resolve(data) {
        //改变状态和数据
        this._changeState(FULLFILLED, data);
    }
    /**
     * 标记当前任务失败
     * @param {any} reason 任务失败的相关数据
     */
    _reject(reason) {
        //改变状态和数据
        this._changeState(REJECTED, reason);
    }
    /**
     * PromiseA+规范的then函数
     * @param {Function} onFullFilled
     * @param {Function} onRejected
     */
    then(onFullFilled, onRejected) {
        //1.注册任务

        return new MyPromise((resolve, rejected) => {
            this._pushHandler(onFullFilled, FULLFILLED, resolve, rejected);
            this._pushHandler(onRejected, REJECTED, resolve, rejected);
            this._runHandlers(); //有的promise是立即resolve的，这时候then还没有注册呢，所以在这里也写上
        });
    }

    /**
     * 仅处理失败的场景
     * @param {Function} onRejected
     */
    catch(onRejected) {
        return this.then(null, onRejected);
    }
    /**
     * 最后要执行的方法
     * @param {Function} onFinally
     * @returns
     */
    finally(onFinally) {
        return this.then(
            (data) => {
                onFinally();
                return data;
            },
            (reason) => {
                onFinally();
                throw reason; //注意这里是throw，而不是return
            }
        );
    }
    
    /**
     * 实现静态方法resolve
     * 特殊情况:
     * 1.传递的data本身就是ES6的Promise对象
     * 2.传递的data是一个PromiseLike 对象
     * 3.传递的data是一个普通值
     * @param {*} data 
     */
    static resolve(data){
        if(data instanceof MyPromise){
            return data
        }else{
            return new MyPromise((resolve,reject)=>{
                if(isPromise(data)){
                    data.then(resolve,reject)
                }else{
                    resolve(data)
                }
                
            })
        }
    }
    /**
     * 得到一个被拒绝的promise
     * @param {*} reason 
     */
    reject(reason){
        return new MyPromise((resolve,reject)=>{
            reject(reason)
        })
    }
}
// const  p1 = new MyPromise((resolve,reject)=>{
//     resolve(1)
// })
// const p2 = p1.then((data)=>{
//     console.log(data)
//     return new Promise((resolve,reject)=>{
//         resolve(2)
//     })
// }).then((data)=>{
//     console.log(data)
// })
// setTimeout(() => {
//     console.log(p1)
//     console.log(p2)
// }, 2000);

let p1 = {then:(resolve,reject)=>{
    resolve(1)
}}
let p2 = p1.then(res=>{
    console.log(res)
})

setTimeout(() => {
    console.log(p1);
    console.log("p2",p2);
}, 1000);